import { computed, CSSProperties, watch } from 'vue'
import { BwStyleModel } from './model'
import { BwStyleStateEnum } from './enum'

/** 把通用渲染样式属性转为样式对象 */
export function getBwStyleModel<T = any>(
  props: T & BwStyleModel,
  mode?: BwStyleStateEnum
): CSSProperties | undefined {
  if (Object.keys(props).length < 1) {
    return undefined
  }
  const obj: CSSProperties = {}

  if (mode === BwStyleStateEnum.hover) {
    /** 弹性盒子 */
    if (props?.display === 'flex') {
      obj.flexDirection = props.hoverFlexDirection
      obj.alignItems = props.hoverAlignItems
      obj.justifyContent = props.hoverJustifyContent
    }

    /** 边框相关 */
    obj.borderLeftWidth = props.hoverBorderLeftWidth
    obj.borderLeftStyle = props.hoverBorderLeftStyle
    obj.borderLeftColor = props.hoverBorderLeftColor

    obj.borderTopWidth = props.hoverBorderTopWidth
    obj.borderTopStyle = props.hoverBorderTopStyle
    obj.borderTopColor = props.hoverBorderTopColor

    obj.borderRightWidth = props.hoverBorderRightWidth
    obj.borderRightStyle = props.hoverBorderRightStyle
    obj.borderRightColor = props.hoverBorderRightColor

    obj.borderBottomWidth = props.hoverBorderBottomWidth
    obj.borderBottomStyle = props.hoverBorderBottomStyle
    obj.borderBottomColor = props.hoverBorderBottomColor

    // 阴影
    const hoverShadowX = props.hoverShadowX
    const hoverShadowY = props.hoverShadowY
    const hoverShadowBlur = props.hoverShadowBlur
    const hoverShadowSpread = props.hoverShadowSpread
    const hoverShadowColor = props.hoverShadowColor
    if (
      hoverShadowX ||
      hoverShadowY ||
      hoverShadowBlur ||
      hoverShadowSpread ||
      hoverShadowColor
    ) {
      obj.boxShadow = `${hoverShadowX ?? '0'} ${hoverShadowY ?? '0'} ${
        hoverShadowBlur ?? '0'
      } ${hoverShadowSpread ?? '0'} ${hoverShadowColor ?? ''}`
    }

    // 背景图片部分
    const hoverBackgroundImage = props.hoverBackgroundImage
    if (hoverBackgroundImage) {
      obj.backgroundImage = `url(${hoverBackgroundImage})`
    }
    obj.backgroundPositionX = props.activeBackgroundPositionX
    obj.backgroundPositionY = props.activeBackgroundPositionY

    const hoverBackgroundSize = props.hoverBackgroundSize
    if (hoverBackgroundSize) {
      obj.backgroundSize = hoverBackgroundSize
    } else {
      const hoverBackgroundSizeWidth = props.hoverBackgroundSizeWidth
      const hoverBackgroundSizeHeight = props.hoverBackgroundSizeHeight
      if (hoverBackgroundSizeWidth || hoverBackgroundSizeHeight)
        obj.backgroundSize = `${hoverBackgroundSizeWidth ?? ''} ${
          hoverBackgroundSizeHeight ?? ''
        }`
    }

    obj.backgroundRepeat = props.hoverBackgroundRepeat
    obj.backgroundAttachment = props.hoverBackgroundAttachment

    return {
      width: props.hoverWidth,
      height: props.hoverHeight,
      display: props.hoverDisplay,
      flexGrow: props.hoverFlexGrow,

      // 外边距
      marginLeft: props.hoverMarginLeft,
      marginTop: props.hoverMarginTop,
      marginRight: props.hoverMarginRight,
      marginBottom: props.hoverMarginBottom,

      // 内边距
      paddingLeft: props.hoverPaddingLeft,
      paddingTop: props.hoverPaddingTop,
      paddingRight: props.hoverPaddingRight,
      paddingBottom: props.hoverPaddingBottom,

      // 字体相关
      fontFamily: props.hoverFontFamily,
      fontWeight: props.hoverFontWeight,
      fontStyle: props.hoverFontStyle,
      color: props.hoverColor,
      fontSize: props.hoverFontSize,
      lineHeight: props.hoverLineHeight,
      textAlign: props.hoverTextAlign,
      textDecoration: props.hoverTextDecoration,

      // 背景相关
      backgroundColor: props.hoverBackgroundColor,

      // 圆角相关
      borderTopLeftRadius: props.hoverBorderTopLeftRadius,
      borderTopRightRadius: props.hoverBorderTopRightRadius,
      borderBottomLeftRadius: props.hoverBorderBottomLeftRadius,
      borderBottomRightRadius: props.hoverBorderBottomRightRadius,

      /** 透明度 */
      opacity: props.hoverOpacity,

      /** 鼠标样式 */
      cursor: props.hoverCursor,
      ...obj,
    }
  } else if (mode === BwStyleStateEnum.focus) {
    /** 弹性盒子 */
    if (props?.display === 'flex') {
      obj.flexDirection = props.focusFlexDirection
      obj.alignItems = props.focusAlignItems
      obj.justifyContent = props.focusJustifyContent
    }

    /** 边框相关 */
    obj.borderLeftWidth = props.focusBorderLeftWidth
    obj.borderLeftStyle = props.focusBorderLeftStyle
    obj.borderLeftColor = props.focusBorderLeftColor

    obj.borderTopWidth = props.focusBorderTopWidth
    obj.borderTopStyle = props.focusBorderTopStyle
    obj.borderTopColor = props.focusBorderTopColor

    obj.borderRightWidth = props.focusBorderRightWidth
    obj.borderRightStyle = props.focusBorderRightStyle
    obj.borderRightColor = props.focusBorderRightColor

    obj.borderBottomWidth = props.focusBorderBottomWidth
    obj.borderBottomStyle = props.focusBorderBottomStyle
    obj.borderBottomColor = props.focusBorderBottomColor

    // 阴影
    const focusShadowX = props.focusShadowX
    const focusShadowY = props.focusShadowY
    const focusShadowBlur = props.focusShadowBlur
    const focusShadowSpread = props.focusShadowSpread
    const focusShadowColor = props.focusShadowColor
    if (
      focusShadowX ||
      focusShadowY ||
      focusShadowBlur ||
      focusShadowSpread ||
      focusShadowColor
    ) {
      obj.boxShadow = `${focusShadowX ?? '0'} ${focusShadowY ?? '0'} ${
        focusShadowBlur ?? '0'
      } ${focusShadowSpread ?? '0'} ${focusShadowColor ?? ''}`
    }

    // 背景图片部分
    const focusBackgroundImage = props.focusBackgroundImage
    if (focusBackgroundImage) {
      obj.backgroundImage = `url(${focusBackgroundImage})`
    }
    obj.backgroundPositionX = props.focusBackgroundPositionX
    obj.backgroundPositionY = props.focusBackgroundPositionY

    const focusBackgroundSize = props.focusBackgroundSize
    if (focusBackgroundSize) {
      obj.backgroundSize = focusBackgroundSize
    } else {
      const focusBackgroundSizeWidth = props.focusBackgroundSizeWidth
      const focusBackgroundSizeHeight = props.focusBackgroundSizeHeight
      if (focusBackgroundSizeWidth || focusBackgroundSizeHeight)
        obj.backgroundSize = `${focusBackgroundSizeWidth ?? ''} ${
          focusBackgroundSizeHeight ?? ''
        }`
    }

    obj.backgroundRepeat = props.focusBackgroundRepeat
    obj.backgroundAttachment = props.focusBackgroundAttachment

    return {
      width: props.focusWidth,
      height: props.focusHeight,
      display: props.focusDisplay,
      flexGrow: props.focusFlexGrow,

      // 外边距
      marginLeft: props.focusMarginLeft,
      marginTop: props.focusMarginTop,
      marginRight: props.focusMarginRight,
      marginBottom: props.focusMarginBottom,

      // 内边距
      paddingLeft: props.focusPaddingLeft,
      paddingTop: props.focusPaddingTop,
      paddingRight: props.focusPaddingRight,
      paddingBottom: props.focusPaddingBottom,

      // 字体相关
      fontFamily: props.focusFontFamily,
      fontWeight: props.focusFontWeight,
      fontStyle: props.focusFontStyle,
      color: props.focusColor,
      fontSize: props.focusFontSize,
      lineHeight: props.focusLineHeight,
      textAlign: props.focusTextAlign,
      textDecoration: props.focusTextDecoration,

      // 背景相关
      backgroundColor: props.focusBackgroundColor,

      // 圆角相关
      borderTopLeftRadius: props.focusBorderTopLeftRadius,
      borderTopRightRadius: props.focusBorderTopRightRadius,
      borderBottomLeftRadius: props.focusBorderBottomLeftRadius,
      borderBottomRightRadius: props.focusBorderBottomRightRadius,

      /** 透明度 */
      opacity: props.focusOpacity,

      /** 鼠标样式 */
      cursor: props.focusCursor,
      ...obj,
    }
  } else if (mode === BwStyleStateEnum.active) {
    /** 弹性盒子 */
    if (props?.display === 'flex') {
      obj.flexDirection = props.activeFlexDirection
      obj.alignItems = props.activeAlignItems
      obj.justifyContent = props.activeJustifyContent
    }

    /** 边框相关 */
    obj.borderLeftWidth = props.activeBorderLeftWidth
    obj.borderLeftStyle = props.activeBorderLeftStyle
    obj.borderLeftColor = props.activeBorderLeftColor

    obj.borderTopWidth = props.activeBorderTopWidth
    obj.borderTopStyle = props.activeBorderTopStyle
    obj.borderTopColor = props.activeBorderTopColor

    obj.borderRightWidth = props.activeBorderRightWidth
    obj.borderRightStyle = props.activeBorderRightStyle
    obj.borderRightColor = props.activeBorderRightColor

    obj.borderBottomWidth = props.activeBorderBottomWidth
    obj.borderBottomStyle = props.activeBorderBottomStyle
    obj.borderBottomColor = props.activeBorderBottomColor

    // 阴影
    const activeShadowX = props.activeShadowX
    const activeShadowY = props.activeShadowY
    const activeShadowBlur = props.activeShadowBlur
    const activeShadowSpread = props.activeShadowSpread
    const activeShadowColor = props.activeShadowColor
    if (
      activeShadowX ||
      activeShadowY ||
      activeShadowBlur ||
      activeShadowSpread ||
      activeShadowColor
    ) {
      obj.boxShadow = `${activeShadowX ?? '0'} ${activeShadowY ?? '0'} ${
        activeShadowBlur ?? '0'
      } ${activeShadowSpread ?? '0'} ${activeShadowColor ?? ''}`
    }

    // 背景图片部分
    const activeBackgroundImage = props.activeBackgroundImage
    if (activeBackgroundImage) {
      obj.backgroundImage = `url(${activeBackgroundImage})`
    }
    obj.backgroundPositionX = props.activeBackgroundPositionX
    obj.backgroundPositionY = props.activeBackgroundPositionY

    const activeBackgroundSize = props.activeBackgroundSize
    if (activeBackgroundSize) {
      obj.backgroundSize = activeBackgroundSize
    } else {
      const activeBackgroundSizeWidth = props.activeBackgroundSizeWidth
      const activeBackgroundSizeHeight = props.activeBackgroundSizeHeight
      if (activeBackgroundSizeWidth || activeBackgroundSizeHeight)
        obj.backgroundSize = `${activeBackgroundSizeWidth ?? ''} ${
          activeBackgroundSizeHeight ?? ''
        }`
    }

    obj.backgroundRepeat = props.activeBackgroundRepeat
    obj.backgroundAttachment = props.activeBackgroundAttachment

    return {
      width: props.activeWidth,
      height: props.activeHeight,
      display: props.activeDisplay,
      flexGrow: props.activeFlexGrow,

      // 外边距
      marginLeft: props.activeMarginLeft,
      marginTop: props.activeMarginTop,
      marginRight: props.activeMarginRight,
      marginBottom: props.activeMarginBottom,

      // 内边距
      paddingLeft: props.activePaddingLeft,
      paddingTop: props.activePaddingTop,
      paddingRight: props.activePaddingRight,
      paddingBottom: props.activePaddingBottom,

      // 字体相关
      fontFamily: props.activeFontFamily,
      fontWeight: props.activeFontWeight,
      fontStyle: props.activeFontStyle,
      color: props.activeColor,
      fontSize: props.activeFontSize,
      lineHeight: props.activeLineHeight,
      textAlign: props.activeTextAlign,
      textDecoration: props.activeTextDecoration,

      // 背景相关
      backgroundColor: props.activeBackgroundColor,

      // 圆角相关
      borderTopLeftRadius: props.activeBorderTopLeftRadius,
      borderTopRightRadius: props.activeBorderTopRightRadius,
      borderBottomLeftRadius: props.activeBorderBottomLeftRadius,
      borderBottomRightRadius: props.activeBorderBottomRightRadius,

      /** 透明度 */
      opacity: props.activeOpacity,

      /** 鼠标样式 */
      cursor: props.activeCursor,
      ...obj,
    }
  } else {
    /** 弹性盒子 */
    if (props?.display === 'flex') {
      obj.flexDirection = props.flexDirection
      obj.alignItems = props.alignItems
      obj.justifyContent = props.justifyContent
    }

    /** 边框相关 */
    obj.borderLeftWidth = props.borderLeftWidth
    obj.borderLeftStyle = props.borderLeftStyle
    obj.borderLeftColor = props.borderLeftColor

    obj.borderTopWidth = props.borderTopWidth
    obj.borderTopStyle = props.borderTopStyle
    obj.borderTopColor = props.borderTopColor

    obj.borderRightWidth = props.borderRightWidth
    obj.borderRightStyle = props.borderRightStyle
    obj.borderRightColor = props.borderRightColor

    obj.borderBottomWidth = props.borderBottomWidth
    obj.borderBottomStyle = props.borderBottomStyle
    obj.borderBottomColor = props.borderBottomColor

    // 阴影
    const shadowX = props.shadowX
    const shadowY = props.shadowY
    const shadowBlur = props.shadowBlur
    const shadowSpread = props.shadowSpread
    const shadowColor = props.shadowColor
    if (shadowX || shadowY || shadowBlur || shadowSpread || shadowColor) {
      obj.boxShadow = `${shadowX ?? '0'} ${shadowY ?? '0'} ${
        shadowBlur ?? '0'
      } ${shadowSpread ?? '0'} ${shadowColor ?? ''}`
    }

    // 背景图片部分
    const backgroundImage = props.backgroundImage
    if (backgroundImage) {
      obj.backgroundImage = `url(${backgroundImage})`
    }
    obj.backgroundPositionX = props.backgroundPositionX
    obj.backgroundPositionY = props.backgroundPositionY

    const activeBackgroundSize = props.backgroundSize
    if (activeBackgroundSize) {
      obj.backgroundSize = activeBackgroundSize
    } else {
      const activeBackgroundSizeWidth = props.backgroundSizeWidth
      const activeBackgroundSizeHeight = props.backgroundSizeHeight
      if (activeBackgroundSizeWidth || activeBackgroundSizeHeight)
        obj.backgroundSize = `${activeBackgroundSizeWidth ?? ''} ${
          activeBackgroundSizeHeight ?? ''
        }`
    }

    obj.backgroundRepeat = props.backgroundRepeat
    obj.backgroundAttachment = props.backgroundAttachment

    return {
      width: props.width,
      height: props.height,
      display: props.display,
      flexGrow: props.flexGrow,

      // 外边距
      marginLeft: props.marginLeft,
      marginTop: props.marginTop,
      marginRight: props.marginRight,
      marginBottom: props.marginBottom,

      // 内边距
      paddingLeft: props.paddingLeft,
      paddingTop: props.paddingTop,
      paddingRight: props.paddingRight,
      paddingBottom: props.paddingBottom,

      // 字体相关
      fontFamily: props.fontFamily,
      fontWeight: props.fontWeight,
      fontStyle: props.fontStyle,
      color: props.color,
      fontSize: props.fontSize,
      lineHeight: props.lineHeight,
      textAlign: props.textAlign,
      textDecoration: props.textDecoration,

      // 背景相关
      backgroundColor: props.backgroundColor,

      // 圆角相关
      borderTopLeftRadius: props.borderTopLeftRadius,
      borderTopRightRadius: props.borderTopRightRadius,
      borderBottomLeftRadius: props.borderBottomLeftRadius,
      borderBottomRightRadius: props.borderBottomRightRadius,

      /** 透明度 */
      opacity: props.opacity,

      /** 鼠标样式 */
      cursor: props.cursor,
      ...obj,
    }
  }
}

/**
 * 样式工具
 * @param props 组件props
 * @param isRemoveUndefined 是否去除undefined的键
 * @returns
 */
export function useStyleTool(props: Record<string, any>) {
  /** 当前组件样式id */
  const curComStyleId = `bw_css_style_${Date.now()}`

  /** 当前组件自定义类名 */
  const customClass = computed(() => props.customClass?.join(' '))

  /** 驼峰转短横线 */
  const handleStyleKeys = (key: string) =>
    key.replace(/[A-Z]/g, (str: string) => '-' + str.toLowerCase())

  /** 处理样式对象 去掉value为undefined的键 转为css字符串 */
  const handleStyleObj = (obj = {} as CSSProperties): string => {
    return Object.entries(obj)
      .filter(([_, value]) => value !== undefined)
      .map(([key, value]) => handleStyleKeys(key) + ': ' + value + ';')
      .join('')
  }

  /** 为组件添加样式 */
  const addStyle = (props: BwStyleModel) => {
    // css对象字符串拼接
    const cssStr = handleStyleObj(
      getBwStyleModel(props, BwStyleStateEnum.default)
    )
    const hoverCssStr = handleStyleObj(
      getBwStyleModel(props, BwStyleStateEnum.hover)
    )
    const focusCssStr = handleStyleObj(
      getBwStyleModel(props, BwStyleStateEnum.focus)
    )
    const activeCssStr = handleStyleObj(
      getBwStyleModel(props, BwStyleStateEnum.active)
    )

    /** css内容 */
    let _innerHTML = ''
    _innerHTML += `.${curComStyleId},.${curComStyleId}[bw-css-class]{${cssStr}}`

    _innerHTML += `.${curComStyleId}:hover,.${curComStyleId}[bw-css-class]:hover{${hoverCssStr}}`

    _innerHTML += `.${curComStyleId}:focus,.${curComStyleId}[bw-css-class]:focus{${focusCssStr}}`

    _innerHTML += `.${curComStyleId}:active,.${curComStyleId}[bw-css-class]:active{${activeCssStr}}`

    _innerHTML += getStyleCustom()

    addStyleToHead(curComStyleId, _innerHTML)
  }

  //#region 处理组件自定义样式
  /** 获取组件自定义样式 */
  const getStyleCustom = () => {
    const css = props.customStyle?.replace(
      /:root/g,
      `.${curComStyleId},.${curComStyleId}[bw-css-class]`
    )
    if (css) {
      // console.log({ css })
      // console.log('props.customClass', props.customClass)
      return css
    }
    return ''
  }
  //#endregion

  watch(
    () => props,
    (newProps) => {
      addStyle(newProps)
    },
    { immediate: true, deep: true }
  )

  return { curComStyleId, customClass }
}

/**
 * 将样式添加到HTML的head元素中
 * @param id 样式id
 * @param css 样式对象字符串
 */
export const addStyleToHead = (
  id?: Nullable<string | number>,
  css?: Nullable<string>
) => {
  if (id && css) {
    id = id?.toString()
    /** 判断是否已存在组件样式 */
    const curStyle = document.getElementById(id)
    if (curStyle) {
      curStyle.innerHTML = css
    } else {
      const style = document.createElement('style')
      style.id = id
      style.innerHTML = css
      document.head.appendChild(style)
    }
  }
}
